package springapp.service;

import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.xml.bind.JAXBException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import springapp.dao.LocationsDao;
import springapp.entity.LocationEntity;
import springapp.jaxb.Location;
import springapp.jaxb.LocationsConfig;
import springapp.util.Utils;

@Service
public class LocationService implements IServiceConstants, ILocationService,
		ResourceLoaderAware {

	@Autowired(required = true)
	private CacheService cacheService;

	@Autowired(required = true)
	private LocationsDao locationsDao;

	@Autowired(required = true)
	private ResourceService resourceService;

	private ICache<Integer, String> locationCache;

	@SuppressWarnings("unchecked")
	@PostConstruct
	public void initialise() throws IOException {
		try {
			Resource resource = resourceService
					.getResource("classpath:xml/locations.xml");
			LocationsConfig config = Utils.getConfig(resource.getInputStream(),
					new LocationsConfig());
			locationsDao.setInitialized();
			List<LocationEntity> allEntities = getAllEntities();
			List<Location> locations2 = config.getLocations();
			Utils.removeOldElements(locations2, allEntities);

			LocationEntity[] entitiesToSave = new LocationEntity[locations2
					.size()];
			int counter = 0;
			for (Location location : locations2) {
				entitiesToSave[counter++] = new LocationEntity(
						location.getName());
			}
			locationsDao.saveEntities(entitiesToSave);

			Collections.addAll(allEntities, entitiesToSave);

			this.cacheService.addToCache(allEntities, LOCATIONS);

			locationCache = (ICache<Integer, String>) cacheService
					.getCache(LOCATIONS);
			locationsDao.unset();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
	}

	@Transactional(readOnly = true)
	public Integer getLocationId(String location) {
		return this.locationCache.getKeyForValue(location);
	}

	@Transactional
	public List<LocationEntity> getAllEntities() {
		List<LocationEntity> allEntities = locationsDao.getAllEntities();
		return allEntities;
	}

	public Set<LocationEntity> getLocationEntities(String[] locations) {
		Set<LocationEntity> entities = new HashSet<LocationEntity>(
				locations.length);

		for (String location : locations) {
			entities.add(new LocationEntity(this.locationCache
					.getKeyForValue(location), location));
		}

		return entities;
	}

	public Set<LocationEntity> getLocationEntities(Integer[] locationIds) {
		Set<LocationEntity> entities = new HashSet<LocationEntity>(
				locationIds.length);

		for (Integer location : locationIds) {
			entities.add(new LocationEntity(location, this.locationCache
					.getValueForKey(location)));
		}

		return entities;
	}

	public String getLocationName(Integer locationId) {
		return this.locationCache.getValueForKey(locationId);
	}

	public Set<String> getAllLocations() {
		return this.locationCache.getValues();
	}

	public void setResourceLoader(ResourceLoader arg0) {

	}

}
